package com.future.baselib.http;

import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.text.TextUtils;

import com.future.baselib.entity.BaseResponse;
import com.future.baselib.entity.DefaultFileResponse;
import com.future.baselib.utils.FLog;
import com.future.baselib.utils.MD5;
import com.future.baselib.utils.ToastUtils;
import com.google.gson.Gson;


import java.io.File;
import java.util.Map;
import java.util.TreeMap;
import java.util.concurrent.TimeUnit;

import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.RequestBody;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.scalars.ScalarsConverterFactory;

/**
 */
@SuppressWarnings("unused")
public class HttpRequest<T extends BaseResponse> {

    private static final String BASE_URL = "http://www.hedongjun.top/";
    private static final String NETWORK_KEY = "1e56c95504a9a846e4c7043704a20f25";

    private static HttpService httpService;

    private Context context;

    private TreeMap<String, String> params;

    private OnNetworkSuccess successListener;
    private OnNetworkFail failListener = new OnNetworkFail() {
        @Override
        public void onFail(String message) {
            ToastUtils.longToast(context, message);
        }
    };
    private String path;

    private static HttpService getHttpService() {
        if (httpService == null) {
            httpService = initRetrofit();
        }
        return httpService;
    }

    private static HttpService initRetrofit() {
        int readTimeout = 5;
        int writeTimeout = 10;
        HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
        interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
        OkHttpClient client = new OkHttpClient.Builder()
                .addNetworkInterceptor(interceptor)
                .connectTimeout(readTimeout, TimeUnit.SECONDS)
                .writeTimeout(writeTimeout, TimeUnit.SECONDS)
                .readTimeout(readTimeout, TimeUnit.SECONDS)
                .build();

        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(BASE_URL)
                .addConverterFactory(ScalarsConverterFactory.create())
                .client(client)
                .build();

        return retrofit.create(HttpService.class);
    }


    public HttpRequest with(Context context) {
        this.context = context;
        return this;
    }

    public HttpRequest setApiCode(String apiCode) {
        if (params == null) {
            params = new TreeMap<>();
        }
        params.put("apiCode", apiCode);
        return this;
    }

    public HttpRequest addParam(String key, String values) {
        if (params == null) {
            params = new TreeMap<>();
        }
        if (TextUtils.isEmpty(values)) {
            return this;
        }
        params.put(key, values);
        return this;
    }

    public HttpRequest setPath(String path){
        this.path = path;
        return this;
    }

    public HttpRequest addParam(String key, int values) {
        if (params == null) {
            params = new TreeMap<>();
        }
        params.put(key, "" + values);
        return this;
    }

    public HttpRequest addParams(TreeMap<String, String> params) {
        if (this.params == null) {
            this.params = new TreeMap<>();
        }
        this.params.putAll(params);
        return this;
    }

    public HttpRequest addSuccessListener(OnNetworkSuccess listener) {
        successListener = listener;
        return this;
    }

    public HttpRequest addFailListener(OnNetworkFail listener) {
        failListener = listener;
        return this;
    }

    public HttpRequest start(final BaseResponse t) {
        if (context == null) {
            FLog.e("context不能为空");
            return this;
        }
        if (params == null) {
            params = new TreeMap<>();
        }
        if (successListener == null) {
            FLog.e("请添加网络请求成功监听successListener");
            return this;
        }
//
//        StringBuilder builder = new StringBuilder();
//        for (Map.Entry<String, String> entry : params.entrySet()) {
//            builder.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
//        }
//        FLog.e("requestValue:\n"+builder.toString());

        if (checkNetworkStatus()) {
            getHttpService()
                    .getData(path,params)
                    .enqueue(new Callback<String>() {
                        @Override
                        public void onResponse(Call<String> call, Response<String> response) {
                            t.parseJson(response.body());
                            if (!TextUtils.isEmpty(response.body()) && t.code == 1) {
                                successListener.onSuccess(t);
                            } else {
                                if (TextUtils.isEmpty(response.body())) {
                                    t.msg = "网络异常，请重试";
                                }
                                failListener.onFail(t.msg);
                            }
                        }

                        @Override
                        public void onFailure(Call<String> call, Throwable t) {
                            ToastUtils.longToast(context, t.getMessage());
                            failListener.onFail(t.getMessage());
                        }
                    });
        } else {
            failListener.onFail("当前无网络连接，请检查网络后重试");
        }
        return this;
    }

    public HttpRequest uploadFile(File file){
        if (context == null) {
            FLog.e("context不能为空");
            return this;
        }
        if (TextUtils.isEmpty(path)) {
            FLog.e("请添加path");
            return this;
        }
        if (successListener == null) {
            FLog.e("请添加网络请求成功监听successListener");
            return this;
        }

        //构建body
        RequestBody requestBody = new MultipartBody.Builder().setType(MultipartBody.FORM)
                .addFormDataPart("file", file.getName(), RequestBody.create(MediaType.parse("image/*"), file))
                .build();


        if (checkNetworkStatus()) {
            getHttpService()
                    .uploadFile(path,requestBody)
                    .enqueue(new Callback<String>() {
                        @Override
                        public void onResponse(Call<String> call, Response<String> response) {
                            DefaultFileResponse fileResponse = new DefaultFileResponse();
                            fileResponse.parseJson(response.body());
                            if (!TextUtils.isEmpty(response.body()) && fileResponse.code == 1) {
                                successListener.onSuccess(fileResponse);
                            } else {
                                if (TextUtils.isEmpty(response.body())) {
                                    fileResponse.msg = "网络异常，请重试";
                                }
                                failListener.onFail(fileResponse.msg);
                            }
                        }

                        @Override
                        public void onFailure(Call<String> call, Throwable t) {
                            ToastUtils.longToast(context, t.getMessage());
                            failListener.onFail(t.getMessage());
                        }
                    });
        } else {
            failListener.onFail("当前无网络连接，请检查网络后重试");
        }
        return this;
    }

    /**
     * 生成请求token
     */
    private String getPostToken(TreeMap<String, String> params) {

        StringBuilder stringBuilder = new StringBuilder();
        for (Map.Entry<String, String> entry : params.entrySet()) {
            stringBuilder.append(entry.getValue());
        }
        return MD5.Md5(stringBuilder.append(NETWORK_KEY).toString());
    }

    /**
     * 请求参数封装成json串
     */
    private String postJson(TreeMap<String, String> params) {
//        String token = getPostToken(params);
//        params.put("token", token);
        String json = new Gson().toJson(params);
//        String requestParams = "";
//        for (String s : params.keySet()) {
//            requestParams += s + "=" + params.get(s) + "&";
//        }
        FLog.e("requestJson" + json);
        return json;
    }

    /**
     * 检查网络状态
     */
    private boolean checkNetworkStatus() {
        ConnectivityManager connMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);

        NetworkInfo networkInfo = connMgr.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
        Boolean isWifiConn = networkInfo.isConnected();

        networkInfo = connMgr.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
        Boolean isMobileConn = networkInfo.isConnected();

        return isMobileConn || isWifiConn;
    }

    public interface OnNetworkSuccess<T extends BaseResponse> {
        void onSuccess(T response);
    }

    public interface OnNetworkFail {
        void onFail(String message);
    }

    public static String returnBaseUrl() {
        return BASE_URL;
    }
}
